<?php

abstract class Config_Exception extends CMS_Exception {

}

class Config_Not_Found_Exception extends Config_Exception {

	protected $_child;

	public function getExceptionTrace(){
		return $this->getCode() . " " . $this->_child->getCode();
	}

	public function __construct($child){
		$this->_child = $child;
	}

}

class Config implements ArrayAccess {

	static $instance;

	private function __construct(){
		$this->data = array();
	}

	public static function createInstance(){
		Config::$instance = new Config();
		return Config::$instance;
	}

	public static function getInstance(){
		if(!isset(Config::$instance)){
			Config::createInstance();
		}
	
		return Config::$instance;
	}

	private static function array_merger($a1, $a2){
		foreach($a2 as $k => $v){
			if(is_int($k)){
				$a1[] = $v;
			} else if(!isset($a1[$k])) {
				$a1[$k] = $v;
			} else if(!is_array($a1[$k]) && !is_array($a2[$k])) {
				$a1[$k] = $v;
			} else if(is_array($a1[$k]) && is_array($a2[$k])) {
				Config::array_merger($a1[$k], $a2[$k]);	
			} else if(is_array($a1[$k])) {
				$a1[$k][] = $v;
			} else if(is_array($a2[$k])) {
				array_unshift($a2[$k], $a1[$k]);
				$a1[$k] = $a2[$k];
			}			
		}
		return $a1;
	}

	public function offsetSet($offset, $value) {
		if(isset($this->data[$offset])){
			$this->data[$offset] = Config::array_merger($this->data[$offset], $value);
		} else {
			$this->data[$offset] = $value;
		}
	}
	public function offsetExists($offset) {
		return isset($this->data[$offset]);
	}
	public function offsetUnset($offset) {
		unset($this->data[$offset]);
	}
	public function offsetGet($offset) {
		return isset($this->data[$offset]) ? $this->data[$offset] : null;
	}


	public static function Load($filename = null){
		if(isset($filename)){
			try {
				CMS::File("config/{$filename}");
			} catch (CMS_File_Exception $e) {
				throw new Config_Not_Found_Exception($e);
			}
			return;
		}

		Config::Load('default');

	}







}
